package com.wsc.personalblog.security;


import com.wsc.personalblog.DTO.UserDTO;
import com.wsc.personalblog.common.Constant;
import com.wsc.personalblog.entity.Role;
import com.wsc.personalblog.entity.User;
import com.wsc.personalblog.exception.LoginFailException;
import com.wsc.personalblog.service.RoleService;
import com.wsc.personalblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    @Autowired
    BCryptPasswordEncoder cryptPasswordEncoder;

    /**
     * 根据username查询出该用户的信息及权限信息。封装成一个UserDetails返回
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if(username.contains(Constant.USER_QQ_MAILBOX_V_CODE)){
            String[] split = username.split(":");
            username = split[1];
            return mailCode(username);
        }
        User user = null;
        // 解析前缀，判断是用邮箱还是用用户名进行查询
        if(username.contains(Constant.USERNAME)){
            String[] split = username.split(":");
            username = split[1];
            // 根据用户名查询出用户信息
            user = userService.getUserAndRoleInfoByUsername(username);
        }
        else if(username.contains(Constant.USER_QQ_MAILBOX)){
            String[] split = username.split(":");
            username = split[1];
            // 根据邮箱查询出用户信息
            user = userService.getUserAndRoleInfoByMail(username);
        }
        if(user == null){
            throw new LoginFailException(Constant.MESSAGE_LOGIN_FAILED);
        }
        // 根据用户id查询到角色信息
        Integer userId = user.getId();
        List<Role> roleInfo = roleService.getRoleInfoByUserId(userId);
        List<String> roleStrInfo = roleInfo.stream().map(Role::getName).collect(Collectors.toList());
        // 封装用户信息跟角色权限信息到SecurityAdmin返回
        return new SecurityUser(user,roleStrInfo);
    }
    private UserDetails mailCode(String mail){
        String key = Constant.VERIFICATION_CODE+mail;
        String code = (String)redisTemplate.opsForValue().get(key);
        User user = userService.getUserAndRoleInfoByMail(mail);
        // 根据用户id查询到角色信息
        Integer userId = user.getId();
        List<Role> roleInfo = roleService.getRoleInfoByUserId(userId);
        List<String> roleStrInfo = roleInfo.stream().map(Role::getName).collect(Collectors.toList());
        String encode = cryptPasswordEncoder.encode(code);
        // 将密码修改成验证码，因为是用验证码来登录的，所以用验证码来顶替密码
        user.setPassword(encode);
        // 封装用户信息跟角色权限信息到SecurityAdmin返回
        return new SecurityUser(user,roleStrInfo);
    }
}
